﻿using UnityEngine;

namespace Mars.MeshUI
{
    public abstract class CustomUIGraphic : MonoBehaviour
    {
        protected bool isVisible = true;
        protected bool positionDrity;
        protected bool sizeDrity;
        protected MeshCanvas canvas;
        [SerializeField] public Vector4 rect = default;
        [SerializeField] [HideInInspector] protected VertexData[] vertices = default;
        public Vector2 size = default;
        public Vector2 pivot = default;
        protected Vector3 deltaPostion;
        protected Vector2 deltaSize;
        protected Transform m_CachaTransform;

        public Transform cachaTransform
        {
            get
            {
                if (m_CachaTransform == null)
                {
                    m_CachaTransform = transform;
                }

                return m_CachaTransform;
            }
        }

        public VertexData[] VerticesData
        {
            get { return vertices; }
        }

        private int meshCanvasIndex = 0;
        private VertexHelperEx.VertexIndicType indicType = VertexHelperEx.VertexIndicType.VertexQuad;

        public int MeshCanvasIndex
        {
            get => meshCanvasIndex;
            set => meshCanvasIndex = value;
        }

        public VertexHelperEx.VertexIndicType IndicType
        {
            get => indicType;
            set => indicType = value;
        }

        public abstract bool Init(MeshCanvas _canvas);

        public abstract bool Rebuild();

        public virtual void UpdateInstancePara(int idx)
        {
        }

        public virtual void InstanceSyncColor(int idx)
        {
        }

        public virtual void OnPopulateMesh(VertexHelperEx toFill)
        {
        }

        public virtual void ClearVertexData()
        {
            vertices = null;
        }


        public virtual void SetCanvasFlagDirty(MeshCanvasDirtyFlag flag)
        {
            if (canvas)
            {
                canvas.SetFlagDirtyById(MeshCanvasIndex, flag);
            }
        }

        public virtual void SetSize(Vector2 s)
        {
            if (s == size)
            {
                return;
            }

            Vector2 tmp = (s - size) / 2;

            rect.x -= tmp.x;
            rect.z += tmp.x;
            rect.y -= tmp.y;
            rect.w += tmp.y;

            size = s;
            deltaSize += tmp;
            sizeDrity = true;
        }

        public virtual void SetPosition(Vector3 localPosition)
        {
            if (localPosition == cachaTransform.localPosition)
            {
                return;
            }

            float deltaX = localPosition.x - cachaTransform.localPosition.x;
            float deltaY = localPosition.y - cachaTransform.localPosition.y;
            float deltaZ = localPosition.z - cachaTransform.localPosition.z;

            rect.x += deltaX;
            rect.z += deltaX;
            rect.y += deltaY;
            rect.w += deltaY;

            deltaPostion.x += deltaX;
            deltaPostion.y += deltaY;
            deltaPostion.z += deltaZ;

            positionDrity = true;
            cachaTransform.localPosition = localPosition;
        }

        protected virtual void RefreshPostion()
        {
            if (positionDrity == false)
            {
                return;
            }


            for (int i = 0; i < vertices.Length; i++)
            {
                vertices[i].position += deltaPostion;
            }

            SetCanvasFlagDirty(MeshCanvasDirtyFlag.kPosition);
        }

        public bool GetVisable()
        {
            return isVisible;
        }

        void OnEnable()
        {
            SetVisable(true);
        }

        void OnDisable()
        {
            SetVisable(false);
        }

        public virtual void SetVisable(bool enable)
        {
            isVisible = enable;

            if (canvas != null)
            {
                canvas.SetVisibleDirtyById(MeshCanvasIndex, enable);
            }
        }
    }
}